using UnityEngine;

namespace utils
{
    /// <summary>
    /// 摄像机视角自由移动
    /// https://gist.github.com/gunderson/d7f096bd07874f31671306318019d996
    /// </summary>
    public class CameraFreeMove : MonoBehaviour
    {
        public float mainSpeed = 100.0f; //regular speed
        public float shiftAdd = 250.0f; //multiplied by how long shift is held.  Basically running
        public float maxShift = 1000.0f; //Maximum speed when holdin gshift
        public float camSens = 0.25f; //How sensitive it with mouse

        //kind of in the middle of the screen, rather than at the top (play)
        private Vector3 _lastMouse = new Vector3(255, 255, 255);
        private float _totalRun = 1.0f;

        void Update()
        {
            _lastMouse = Input.mousePosition - _lastMouse;
            _lastMouse = new Vector3(-_lastMouse.y * camSens, _lastMouse.x * camSens, 0);
            var eulerAngles = transform.eulerAngles;
            _lastMouse = new Vector3(eulerAngles.x + _lastMouse.x, eulerAngles.y + _lastMouse.y, 0);
            transform.eulerAngles = _lastMouse;
            _lastMouse = Input.mousePosition;
            //Mouse  camera angle done.  

            //Keyboard commands
            Vector3 p = GetBaseInput();
            if (p.sqrMagnitude > 0)
            {
                // only move while a direction key is pressed
                if (Input.GetKey(KeyCode.LeftShift))
                {
                    _totalRun += Time.deltaTime;
                    p = p * _totalRun * shiftAdd;
                    p.x = Mathf.Clamp(p.x, -maxShift, maxShift);
                    p.y = Mathf.Clamp(p.y, -maxShift, maxShift);
                    p.z = Mathf.Clamp(p.z, -maxShift, maxShift);
                }
                else
                {
                    _totalRun = Mathf.Clamp(_totalRun * 0.5f, 1f, 1000f);
                    p = p * mainSpeed;
                }

                p = p * Time.deltaTime;
                Vector3 newPosition = transform.position;
                if (Input.GetKey(KeyCode.Space))
                {
                    //If player wants to move on X and Z axis only
                    transform.Translate(p);
                    newPosition.x = transform.position.x;
                    newPosition.z = transform.position.z;
                    transform.position = newPosition;
                }
                else
                {
                    transform.Translate(p);
                }
            }
        }

        private Vector3 GetBaseInput()
        {
            //returns the basic values, if it's 0 than it's not active.
            Vector3 pVelocity = new Vector3();
            if (Input.GetKey(KeyCode.W))
            {
                pVelocity += new Vector3(0, 0, 1);
            }

            if (Input.GetKey(KeyCode.S))
            {
                pVelocity += new Vector3(0, 0, -1);
            }

            if (Input.GetKey(KeyCode.A))
            {
                pVelocity += new Vector3(-1, 0, 0);
            }

            if (Input.GetKey(KeyCode.D))
            {
                pVelocity += new Vector3(1, 0, 0);
            }

            return pVelocity;
        }
    }
}